import cv2
import numpy as np
from pynput import mouse, keyboard
from pynput.mouse import Listener as MouseListener
from pynput.keyboard import Listener as KeyboardListener
import threading
import time
import pystray
from PIL import Image, ImageDraw, ImageFont
import win32gui
import win32con

# 全局托盘图标对象
tray_icon = None

# 用于存储操作信息和坐标
operation_info = []
stop_event = threading.Event()  # 用于控制线程停止

# 创建一个 OpenCV 窗口
screen_width = 800  # 屏幕宽度
screen_height = 200  # 屏幕高度
window_name = "Operation record"

# 创建一个黑色背景图像
background = np.zeros((screen_height, screen_width, 3), dtype=np.uint8)

# 显示的文本框配置
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 0.6
font_color = (0, 0, 0)  # 黑色字体
thickness = 2
line_type = cv2.LINE_AA

# 半透明矩形背景颜色
rect_color = (255, 255, 255)  # 白色背景
rect_alpha = 0.4  # 透明度（0 到 1 之间的值，0 完全透明，1 完全不透明）

# 用于显示信息的文本框
def show_text():
    global tray_icon
    while not stop_event.is_set():
        # 复制背景图像
        display_img = background.copy()

        # 显示操作信息
        y_offset = 20
        for info in operation_info[-3:]:  # 只显示最后三条操作记录
            text = f"{info[0]} - Mouse Position: {info[1]}"

            # 计算文本框大小
            (text_width, text_height), baseline = cv2.getTextSize(text, font, font_scale, thickness)

            # 计算文本框的左上角和右下角
            rect_top_left = (10, y_offset - 10)
            rect_bottom_right = (10 + text_width + 20, y_offset + text_height + 10)

            # 在文本框区域绘制一个半透明矩形
            overlay = display_img.copy()
            cv2.rectangle(overlay, rect_top_left, rect_bottom_right, rect_color, -1)
            cv2.addWeighted(overlay, rect_alpha, display_img, 1 - rect_alpha, 0, display_img)

            # 在矩形框内绘制文本
            cv2.putText(display_img, text, (10 + 10, y_offset + text_height), font, font_scale, font_color, thickness, line_type)

            # 更新 y_offset
            y_offset += text_height + 30

        # 显示文本框
        cv2.imshow(window_name, display_img)

        # 获取窗口句柄并将其置顶
        hwnd = win32gui.FindWindow(None, window_name)  # 获取窗口句柄
        if hwnd:
            win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)

        # 每次更新后暂停 0.1 秒
        time.sleep(0.1)

        # 按下 'q' 键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            stop_event.set()  # 设置停止标志退出
            if tray_icon is not None:
                tray_icon.stop()  # 停止托盘图标
            break

        # 每次更新后暂停 0.1 秒
        time.sleep(0.1)

    cv2.destroyAllWindows()


# 监听鼠标事件
def on_move(x, y):
    operation_info.append(('move', (x, y)))

def on_click(x, y, button, pressed):
    action = 'Pressed' if pressed else 'Released'
    operation_info.append((f'Mouse {action} {button}', (x, y)))

# 监听键盘事件
def on_press(key):
    global paused
    try:
        if key == keyboard.Key.esc:
            paused = True  # 按下 Esc 键时暂停监听
        else:
            if not paused:
                operation_info.append((f'Key pressed: {key.char}', None))
    except AttributeError:
        if not paused:
            operation_info.append((f'Key pressed: {key}', None))

def on_release(key):
    global paused
    if key == keyboard.Key.esc:
        paused = False  # 释放 Esc 键时恢复监听
        operation_info.append(('Esc key released', None))

# 创建系统托盘图标
def create_image():
    # 创建一个 64x64 像素的 RGB 图像，背景为白色
    image = Image.new('RGBA', (64, 64), (0, 0, 0, 0))  # (0, 0, 0, 0) 是透明背景
    draw = ImageDraw.Draw(image)
    # 在图像上绘制一个红色填充的圆形
    red_color = (255, 0, 0, 255)  # (255, 0, 0) 是红色，255 是不透明度
    draw.ellipse((0, 0, 64, 64), fill=red_color)  # 在整个图像区域绘制圆形

        # 使用默认字体，并绘制更大的文本
    try:
        font = ImageFont.truetype("arial.ttf", 25)
    except IOError:
        font = ImageFont.load_default()
    

    # 实现文本在图像中央绘制:在图像上绘制文字 "Rec"，文字颜色为白色
    text = "Rec"
    bbox = draw.textbbox((0, 0), text, font=font)
    text_width = bbox[2] - bbox[0]  # 计算文本宽度
    text_height = bbox[3] - bbox[1]  # 计算文本高度

    x = (64 - text_width) // 2  # 水平方向居中
    y = (64 - text_height) // 2  # 垂直方向居中

    draw.text((x, y), text, fill=(255, 255, 255), font=font) # (255, 255, 255) 是白色
    return image

# 退出程序
def on_exit(icon, item):
    stop_event.set()  # 停止所有线程
    icon.stop()

# 启动系统托盘图标
def start_tray_icon():
    global tray_icon
    icon_image = create_image()
    tray_icon = pystray.Icon("operation_recorder", icon_image, menu=pystray.Menu(
        pystray.MenuItem("退出", on_exit)
    ))
    tray_icon.run()


# 启动鼠标监听线程
mouse_listener = MouseListener(on_move=on_move, on_click=on_click)
mouse_thread = threading.Thread(target=mouse_listener.start)
mouse_thread.start()

# 启动键盘监听线程
keyboard_listener = KeyboardListener(on_press=on_press, on_release=on_release)
keyboard_thread = threading.Thread(target=keyboard_listener.start)
keyboard_thread.start()

# 启动显示操作信息的线程
display_thread = threading.Thread(target=show_text)
display_thread.start()

# 启动系统托盘图标线程
tray_thread = threading.Thread(target=start_tray_icon)
tray_thread.start()
